// SIPMessage.cpp: implementation of the CSIPMessage class.
//
//////////////////////////////////////////////////////////////////////
#pragma warning(disable:4530)

#include "SIPMessage.h"
#include "SDPContent.h"


#ifdef USE_DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif


#define COPYOBJECT(T,A,B,V,i)  T *V;if(B.A.size()>0){while(A.empty() == false){V = A.front();A.pop_front();	delete V;}for(std::list<T *>::const_iterator i = B.A.begin();i!=B.A.end();i++){A.push_back(new T(**i));}}else{while(!A.empty()){V = A.front();A.pop_front();delete V;}}

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CSIPMessage::CSIPMessage()
{
	Init();
	timeval tv;
	gettimeofday(&tv, NULL);
    m_usProduceTime = tv.tv_sec * 1000 * 1000  +  tv.tv_usec;
}

CSIPMessage::CSIPMessage(const char *pbuf,int len)
{
	Init();
	int c = Parse(pbuf,len);	
//	this->m_Destination = msg.destination;
//	this->m_Source = msg.source;
    timeval tv;
	gettimeofday(&tv, NULL);
    m_usProduceTime = tv.tv_sec * 1000 * 1000  +  tv.tv_usec;
}
CSIPMessage::CSIPMessage(const CSIPMessage &msg)
{
	Init();
	*this = msg;
}
CSIPMessage::~CSIPMessage()
{
	Clear();
}
int CSIPMessage::ParseVia(const char *pbuf,int len)
{
	const char *p = pbuf;
	int c = 0,c1 = 0;

	CSIPVia *pvia = new CSIPVia;
	c1 = pvia->Parse(p,len);
	if(c1 == -1)
	{
		delete pvia;			
		m_nError = 3;
		return -1;
	}
	m_Vias.push_back(pvia);
	p+=c1;
	c+=c1;
	SKIPLWS(p,len,c,c1);
	while(*p == COMMA)
	{				
		p++;c++;
		SKIPLWS(p,len,c,c1);
		pvia = new CSIPVia;
		c1 = pvia->Parse(p,len - c);
		if(c1 == -1)
		{
			delete pvia;			
			m_nError = 3;
			return -1;
		}	
		p+=c1;
		c+=c1;
		m_Vias.push_back(pvia);
		SKIPLWS(p,len,c,c1);
	}
	return c;
}
int CSIPMessage::ParseContact(const char *pbuf,int len)
{
	const char *p = pbuf;
	int c = 0,c1 = 0;

	CSIPContact *pc = new CSIPContact;
	c1 = pc->Parse(p,len - c);
	if(c1 == -1)
	{
		delete pc;				
		m_nError = 12;
		return -1;
	}
	m_Contacts.push_back(pc);
	p+=c1;
	c+=c1;
	SKIPLWS(p,len,c,c1);
	while(*p == COMMA)
	{				
		p++;c++;
		SKIPLWS(p,len,c,c1);
		pc = new CSIPContact;
		c1 = pc->Parse(p,len - c);
		if(c1 == -1)
		{
			delete pc;			
			m_nError = 12;
			return -1;
		}	
		p+=c1;
		c+=c1;
		m_Contacts.push_back(pc);
		SKIPLWS(p,len,c,c1);
	}
	return c;
}
int CSIPMessage::ParseContentEncoding(const char *pbuf,int len)
{
	const char *p = pbuf;
	int c = 0,c1 = 0;

	CSIPContentEncoding *pallow = new CSIPContentEncoding;
	c1 = pallow->Parse(p,len - c);
	if(c1 == -1)
	{
		delete pallow;
		m_nError = 15;
		return -1;
	}
	p+=c1;
	c+=c1;
	m_ContentEncodings.push_back(pallow);
	SKIPLWS(p,len,c,c1);
	while(*p == COMMA)
	{
		p++;c++;
		SKIPLWS(p,len,c,c1);
		pallow = new CSIPContentEncoding;
		c1 = pallow->Parse(p,len - c);
		if(c1 == -1)
		{
			delete pallow;
			m_nError = 15;
			return -1;
		}
		p+=c1;
		c+=c1;
		m_ContentEncodings.push_back(pallow);
		SKIPLWS(p,len,c,c1);
	}
	return c;
}

int CSIPMessage::ParseAllowEvents(const char *pbuf,int len)
{
	const char *p = pbuf;
	int c = 0,c1 = 0;

	CSIPAllowEvents *pallow = new CSIPAllowEvents;
	c1 = pallow->Parse(p,len - c);
	if(c1 == -1)
	{
		delete pallow;			
		m_nError = 21;
		return -1;
	}	
	p+=c1;
	c+=c1;
	m_AllowEvents.push_back(pallow);
	SKIPLWS(p,len,c,c1);
	while(*p == COMMA)
	{				
		p++;c++;
		SKIPLWS(p,len,c,c1);
		pallow = new CSIPAllowEvents;
		c1 = pallow->Parse(p,len - c);
		if(c1 == -1)
		{
			delete pallow;			
			m_nError = 21;
			return -1;
		}	
		p+=c1;
		c+=c1;
		m_AllowEvents.push_back(pallow);
		SKIPLWS(p,len,c,c1);
	}
	return c;
}
int CSIPMessage::ParseAcceptEncoding(const char *pbuf,int len)
{
	const char *p = pbuf;
	int c = 0,c1 = 0;


	CSIPAcceptEncoding *pallow = new CSIPAcceptEncoding;
	c1 = pallow->Parse(p,len - c);
	if(c1 == -1)
	{
		delete pallow;			
		m_nError = 24;
		return -1;
	}	
	p+=c1;
	c+=c1;
	m_AcceptEncodings.push_back(pallow);
	SKIPLWS(p,len,c,c1);
	while(*p == COMMA)
	{				
		p++;c++;
		SKIPLWS(p,len,c,c1);
		pallow = new CSIPAcceptEncoding;
		c1 = pallow->Parse(p,len - c);
		if(c1 == -1)
		{
			delete pallow;			
			m_nError = 24;
			return -1;
		}	
		p+=c1;
		c+=c1;
		m_AcceptEncodings.push_back(pallow);
		SKIPLWS(p,len,c,c1);
	}
	return c;
}
int CSIPMessage::ParseAcceptLanguage(const char *pbuf,int len)
{
	const char *p = pbuf;
	int c = 0,c1 = 0;
	CSIPAcceptLanguage *pc = new CSIPAcceptLanguage;
	c1 = pc->Parse(p,len - c);
	if(c1 == -1)
	{
		delete pc;				
		m_nError = 25;
		return -1;
	}
	m_AcceptLanguages.push_back(pc);
	p+=c1;
	c+=c1;
	SKIPLWS(p,len,c,c1);
	while(*p == COMMA)
	{				
		p++;c++;
		SKIPLWS(p,len,c,c1);
		pc = new CSIPAcceptLanguage;
		c1 = pc->Parse(p,len - c);
		if(c1 == -1)
		{
			delete pc;			
			m_nError = 25;
			return -1;
		}	
		p+=c1;
		c+=c1;
		m_AcceptLanguages.push_back(pc);
		SKIPLWS(p,len,c,c1);
	}
	return c;
}
int CSIPMessage::ParseNATAddress(const char *pbuf,int len)
{
	const char *p = pbuf;
	int c = 0,c1 = 0;
	CSIPNATAddress *pnataddr = new CSIPNATAddress;
	c1 = pnataddr->Parse(p,len - c);
	if(c1 == -1)
	{
		delete pnataddr;			
		m_nError = 60;
		return -1;
	}	
	p+=c1;
	c+=c1;
	m_NATAddresses.push_back(pnataddr);
	SKIPLWS(p,len,c,c1);
	while(*p == COMMA)
	{				
		p++;c++;
		SKIPLWS(p,len,c,c1);
		pnataddr = new CSIPNATAddress;
		c1 = pnataddr->Parse(p,len - c);
		if(c1 == -1)
		{
			delete pnataddr;			
			m_nError = 24;
			return -1;
		}	
		p+=c1;
		c+=c1;
		m_NATAddresses.push_back(pnataddr);
		SKIPLWS(p,len,c,c1);
	}
	return c;
}
int CSIPMessage::ParseAllow(const char *pbuf,int len)
{
	const char *p = pbuf;
	int c = 0,c1 = 0;
	CSIPAllow *pallow = new CSIPAllow;
	c1 = pallow->Parse(p,len - c);
	if(c1 == -1)
	{
		delete pallow;			
		m_nError = 24;
		return -1;
	}	
	p+=c1;
	c+=c1;
	m_Allows.push_back(pallow);
	SKIPLWS(p,len,c,c1);
	while(*p == COMMA)
	{				
		p++;c++;
		SKIPLWS(p,len,c,c1);
		pallow = new CSIPAllow;
		c1 = pallow->Parse(p,len - c);
		if(c1 == -1)
		{
			delete pallow;			
			m_nError = 24;
			return -1;
		}	
		p+=c1;
		c+=c1;
		m_Allows.push_back(pallow);
		SKIPLWS(p,len,c,c1);
	}
	return c;
}
int CSIPMessage::ParseRequire(const char *pbuf,int len)
{
	const char *p = pbuf;
	int c = 0,c1 = 0;
	CSIPRequire *pc = new CSIPRequire;
	c1 = pc->Parse(p,len - c);
	if(c1 == -1)
	{
		delete pc;				
		m_nError = 27;
		return -1;
	}
	m_Requires.push_back(pc);
	p+=c1;
	c+=c1;
	SKIPLWS(p,len,c,c1);
	while(*p == COMMA)
	{				
		p++;c++;
		SKIPLWS(p,len,c,c1);
		pc = new CSIPRequire;
		c1 = pc->Parse(p,len - c);
		if(c1 == -1)
		{
			delete pc;			
			m_nError = 27;
			return -1;
		}	
		p+=c1;
		c+=c1;
		m_Requires.push_back(pc);
		SKIPLWS(p,len,c,c1);
	}
	return c;
}
int CSIPMessage::ParseContentLanguage(const char *pbuf,int len)
{
	const char *p = pbuf;
	int c = 0,c1 = 0;
	CSIPContentLanguage *pc = new CSIPContentLanguage;
	c1 = pc->Parse(p,len - c);
	if(c1 == -1)
	{
		delete pc;				
		m_nError = 25;
		return -1;
	}
	m_ContentLanguages.push_back(pc);
	p+=c1;
	c+=c1;
	SKIPLWS(p,len,c,c1);
	while(*p == COMMA)
	{				
		p++;c++;
		SKIPLWS(p,len,c,c1);
		pc = new CSIPContentLanguage;
		c1 = pc->Parse(p,len - c);
		if(c1 == -1)
		{
			delete pc;			
			m_nError = 25;
			return -1;
		}	
		p+=c1;
		c+=c1;
		m_ContentLanguages.push_back(pc);
		SKIPLWS(p,len,c,c1);
	}
	return c;
}
int CSIPMessage::Parse(const char *pbuf, int len)
{
	Clear();
	const char *p = pbuf;
	int c = 0;
	int c1;
	c1 = SkipAllWhiteSpace(pbuf,len);
	if(c1 > 0)
	{
		p+=c1;
		c+=c1;
	}
	if(strncmp(p,"SIP",3) == 0)
	{//is status-line
		m_nType = MSG_RESPONSE;		

		m_pStatusLine = new CSIPStatusLine;
		c1 = m_pStatusLine->Parse(p,len - c);
		if(c1 == -1)
		{
			m_nError = 3;//status-line error
			return -1;
		}
		p += c1;
		c += c1;
	}
	else
	{//is Request-line
		m_nType = MSG_REQUEST;
		m_pRequestLine = new CSIPRequestLine;
		c1 = m_pRequestLine->Parse(p,len - c);
		if(c1 == -1)
		{
			m_nError = 2;//request-line error
			return -1;
		}
		p += c1;
		c += c1;
	}
	
	//skip CRLF
	if(strncmp(p,"\r\n",2))
	{
		m_nError = 1;
		return -1;
	}
	p+=2;
	c+=2;
	if(c >= len)
	{
		m_nError = -1;
		return -1;
	}
	mystring name;
	while(1)
	{
		name.erase();
		while(*p != COLON)
		{
			if(*p == SP || *p == HTAB || *p == CR || *p == LF)
				break;
			name += *p;
			p++;
			c++;
			if(c >= len)
			{
				m_nError = -1;
				return -1;
			}
		}
		if(*p != COLON)
		{
			c1 = SkipLWS(p,len - c);
			if(c1 == -1)
			{
				m_nError = -1;
				return -1;
			}
			p+= c1;
			c += c1;
		}
		if(*p != COLON)
		{			
			m_nError = -1;
			return -1;			
		}
		//skip COLON
		p++;
		c++;
		//skip LWS
		c1 = SkipLWS(p,len - c);
		if(c1 == -1)
		{
			m_nError = -1;
			return -1;
		}
		p+= c1;
		c += c1;
		if(stricmp(name.c_str(),"Via") == 0 || name == "v")
		{			
			c1 = ParseVia(p,len-c);
			if(c1 == -1)
				return -1;
			c+=c1;
			p+=c1;
		}
		else if(stricmp(name.c_str(), "From") == 0 || name == "f")
		{
			if(m_pFrom == NULL)				
				m_pFrom = new CSIPFrom();
			c1 = m_pFrom->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pFrom;
				m_pFrom = NULL;
				m_nError = 4;
				return -1;
			}
			p+=c1;
			c+=c1;
		}
		else if(stricmp(name.c_str(),"To") == 0 || name == "t")
		{
			if(m_pTo == NULL)
				m_pTo = new CSIPTo();
			c1 = m_pTo->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pTo;
				m_pTo = NULL;
				m_nError = 5;
				return -1;
			}
			p+=c1;
			c+=c1;
		}
		else if(stricmp(name.c_str(),"Content-Length") == 0)
		{
			if(m_pContentLength == NULL)
				m_pContentLength = new CSIPContentLength;
			c1 = m_pContentLength->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pContentLength;
				m_pContentLength = NULL;
				m_nError = 6;
				return -1;
			}
			p+=c1;
			c+=c1;
		}
		else if(stricmp(name.c_str(),"Content-Type") == 0)
		{
			if(m_pContentType == NULL)
				m_pContentType = new CSIPContentType;
			c1 = m_pContentType->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pContentType;
				m_pContentType = NULL;
				m_nError = 7;
				return -1;
			}
			p+=c1;
			c+=c1;
		}
		else if(stricmp(name.c_str(),"Max-Forwards") == 0)
		{
			if(m_pMaxForwards == NULL)
				m_pMaxForwards = new CSIPMaxForwards;
			c1 = m_pMaxForwards->Parse(p,len - c);
			if(c1 == -1)
			{
				m_nError = 8;
				delete m_pMaxForwards;
				m_pMaxForwards = NULL;
				return -1;
			}
			p+=c1;
			c+=c1;
		}
		else if(stricmp(name.c_str(),"Expires") == 0)
		{
			if(m_pExpires == NULL)
				m_pExpires = new CSIPExpires;
			c1 = m_pExpires->Parse(p,len - c);
			if(c1 == -1)
			{
				m_nError = 9;
				delete m_pExpires;
				m_pExpires = NULL;
				return -1;
			}
			p+=c1;
			c+=c1;
		}	
		//====================
		// CallId:
		//====================
		else if(stricmp(name.c_str(),"Call-ID") == 0 || name == "i")
		{	
			if(m_pCallID == NULL)
				m_pCallID = new CSIPCallID;
			c1 = m_pCallID->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pCallID;
				m_pCallID = NULL;
				m_nError = 10;
				return -1;
			}
			p+=c1;
			c+=c1;
		}
		else if(stricmp(name.c_str(),"CSeq") == 0)
		{			
			if(m_pSequence == NULL)
				m_pSequence = new CSIPSequence;
			c1 = m_pSequence->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pSequence;
				m_pSequence = NULL;
				m_nError = 11;
				return -1;
			}
			p+=c1;
			c+=c1;
		}
		else if(stricmp(name.c_str(),"Contact") == 0 || name == "m")
		{			
			c1 = ParseContact(p,len - c);
			if(c1 == -1)
				return -1;
			c+=c1;
			p+=c1;			
		}
		else if(stricmp(name.c_str(),"Translate") == 0)
		{
			
			if(m_pTranslate == NULL)
				m_pTranslate = new CSIPTranslate;
			c1 = m_pTranslate->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pTranslate;
				m_pTranslate = NULL;
				m_nError = 13;
				return -1;
			}		
			p+=c1;
			c+=c1;			
		}	
		else if(stricmp(name.c_str(),"Date") == 0)
		{
			if(m_pDate == NULL)
				m_pDate = new CSIPDate;
			c1 = m_pDate->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pDate;
				m_pDate = NULL;
				m_nError = 14;
				return -1;
			}		
			p+=c1;
			c+=c1;	
		}		
		else if(stricmp(name.c_str(),"Content-Encoding") == 0)
		{
			c1 = ParseContentEncoding(p,len - c);
			if(c1 == -1)
				return -1;
			c+=c1;
			p+=c1;
		}
		else if(stricmp(name.c_str(),"Content-Transfer-Encoding") == 0)
		{
		}
		else if(stricmp(name.c_str(),"Mime-Version") == 0)
		{
			if(m_pMIMEVersion == NULL)
				m_pMIMEVersion = new CSIPMIMEVersion;
			c1 = m_pMIMEVersion->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pMIMEVersion;
				m_pMIMEVersion = NULL;
				m_nError = 16;
				return -1;
			}		
			p+=c1;
			c+=c1;
		}		
		else if(stricmp(name.c_str(),"Event") == 0 || name == "o")
		{
			if(m_pEvent == NULL)
				m_pEvent = new CSIPEvent;
			c1 = m_pEvent->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pEvent;
				m_pEvent = NULL;
				m_nError = 20;
				return -1;
			}		
			p+=c1;
			c+=c1;	
			
		}
		else if(stricmp(name.c_str(),"Allow-Events") == 0 || name == "u")
		{
			c1 = ParseAllowEvents(p,len - c);
			if(c1 == -1)
				return -1;
			c+=c1;p+=c1;
		}
		else if(stricmp(name.c_str(),"Accept-Encoding") == 0)
		{
			c1 = ParseAcceptEncoding(p,len - c);
			if(c1 == -1)
				return -1;
			c+=c1;p+=c1;
		}
		else if(stricmp(name.c_str(),"Accept-Language") == 0)
		{
			c1 = ParseAcceptLanguage(p,len - c);
			if(c1 == -1)
				return -1;
			c+=c1;p+=c1;
			/*
			CSIPAcceptLanguage *pc = new CSIPAcceptLanguage;
			c1 = pc->Parse(p,len - c);
			if(c1 == -1)
			{
				delete pc;				
				m_nError = 25;
				return -1;
			}
			m_AcceptLanguages.push_back(pc);
			p+=c1;
			c+=c1;
			SKIPLWS(p,len,c,c1);
			while(*p == COMMA)
			{				
				p++;c++;
				SKIPLWS(p,len,c,c1);
				pc = new CSIPAcceptLanguage;
				c1 = pc->Parse(p,len - c);
				if(c1 == -1)
				{
					delete pc;			
					m_nError = 25;
					return -1;
				}	
				p+=c1;
				c+=c1;
				m_AcceptLanguages.push_back(pc);
				SKIPLWS(p,len,c,c1);
			}
			*/
		}
		else if(stricmp(name.c_str(),"NATAddress") == 0)
		{
			c1 = ParseNATAddress(p,len - c);
			if(c1 == -1)
				return -1;
			c+=c1;p+=c1;			
		}
		else if(stricmp(name.c_str(),"Allow") == 0)
		{
			c1 = ParseAllow(p,len - c);
			if(c1 == -1)
				return -1;
			c+=c1;p+=c1;			
		}
		else if(stricmp(name.c_str(),"Content-Language") == 0)
		{				
			c1 = ParseContentLanguage(p,len - c);
			if(c1 == -1)
				return -1;
			c+=c1;p+=c1;			
			
		}		
		else if(stricmp(name.c_str(),"Require") == 0)
		{	
			c1 = ParseRequire(p,len - c);
			if(c1 == -1)
				return -1;
			c+=c1;p+=c1;						
		}
		else if(stricmp(name.c_str(),"Subscription-State") == 0)
		{
			if(m_pSubscriptionState == NULL)
				m_pSubscriptionState = new CSIPSubscriptionState;
			c1 = m_pSubscriptionState->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pSubscriptionState;
				m_pSubscriptionState = NULL;
				m_nError = 29;
				return -1;
			}		
			p+=c1;
			c+=c1;
		}
		else if(stricmp(name.c_str(),"Record-Route") == 0)
		{
			CSIPRoute *pc = new CSIPRoute;
			c1 = pc->Parse(p,len - c);
			if(c1 == -1)
			{
				delete pc;				
				m_nError = 38;
				return -1;
			}
			m_RecordRoutes.push_back(pc);
			p+=c1;
			c+=c1;
			SKIPLWS(p,len,c,c1);
			while(*p == COMMA)
			{				
				p++;c++;
				SKIPLWS(p,len,c,c1);
				pc = new CSIPRoute;
				c1 = pc->Parse(p,len - c);
				if(c1 == -1)
				{
					delete pc;			
					m_nError = 39;
					return -1;
				}	
				p+=c1;c+=c1;
				m_RecordRoutes.push_back(pc);
				SKIPLWS(p,len,c,c1);
			}
		}
		else if(stricmp(name.c_str(),"Route") == 0)
		{
			CSIPRoute *pc = new CSIPRoute;
			c1 = pc->Parse(p,len - c);
			if(c1 == -1)
			{
				delete pc;				
				m_nError = 39;
				return -1;
			}
			m_Routes.push_back(pc);
			p+=c1;c+=c1;
			SKIPLWS(p,len,c,c1);
			while(*p == COMMA)
			{				
				p++;c++;
				SKIPLWS(p,len,c,c1);
				pc = new CSIPRoute;
				c1 = pc->Parse(p,len - c);
				if(c1 == -1)
				{
					delete pc;			
					m_nError = 39;
					return -1;
				}	
				p+=c1;c+=c1;
				m_Routes.push_back(pc);
				SKIPLWS(p,len,c,c1);
			}
		}		
		//====================
		// Integer:
		//====================		
		else if(stricmp(name.c_str(),"Min-Expires") == 0)
		{
			if(m_pMinExpires == NULL)
				m_pMinExpires = new CSIPMinExpires;
			c1 = m_pMinExpires->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pMinExpires;
				m_pMinExpires = NULL;
				m_nError = 48;
				return -1;
			}
			p+=c1;	c+=c1;
		}
//#ifdef PC_CLIENT
		else if(stricmp(name.c_str(),"Supported") == 0 || name == "k")
		{
			CSIPSupported *pc = new CSIPSupported;
			c1 = pc->Parse(p,len - c);
			if(c1 == -1)
			{
				delete pc;				
				m_nError = 28;
				return -1;
			}
			m_Supporteds.push_back(pc);
			p+=c1;
			c+=c1;
			SKIPLWS(p,len,c,c1);
			while(*p == COMMA)
			{				
				p++;c++;
				SKIPLWS(p,len,c,c1);
				pc = new CSIPSupported;
				c1 = pc->Parse(p,len - c);
				if(c1 == -1)
				{
					delete pc;			
					m_nError = 28;
					return -1;
				}	
				p+=c1;
				c+=c1;
				m_Supporteds.push_back(pc);
				SKIPLWS(p,len,c,c1);
			}
		}
		else if(stricmp(name.c_str(),"Proxy-Require") == 0)
		{
			CSIPProxyRequire *pallow = new CSIPProxyRequire;
			c1 = pallow->Parse(p,len - c);
			if(c1 == -1)
			{
				delete pallow;			
				m_nError = 26;
				return -1;
			}	
			p+=c1;
			c+=c1;
			m_ProxyRequires.push_back(pallow);
			SKIPLWS(p,len,c,c1);
			while(*p == COMMA)
			{				
				p++;c++;
				SKIPLWS(p,len,c,c1);
				pallow = new CSIPProxyRequire;
				c1 = pallow->Parse(p,len - c);
				if(c1 == -1)
				{
					delete pallow;			
					m_nError = 26;
					return -1;
				}	
				p+=c1;
				c+=c1;
				m_ProxyRequires.push_back(pallow);
				SKIPLWS(p,len,c,c1);
			}
		}
		else if(stricmp(name.c_str(),"Priority") == 0)
		{
			if(m_pPriority == NULL)
				m_pPriority = new CSIPPriority;
			c1 = m_pPriority->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pPriority;
				m_pPriority = NULL;
				m_nError = 17;
				return -1;
			}		
			p+=c1;
			c+=c1;
		}
		else if(stricmp(name.c_str(),"Unsupported") == 0)
		{
			CSIPUnsupported *pc = new CSIPUnsupported;
			c1 = pc->Parse(p,len - c);
			if(c1 == -1)
			{
				delete pc;				
				m_nError = 30;
				return -1;
			}
			m_Unsupporteds.push_back(pc);
			p+=c1;
			c+=c1;
			SKIPLWS(p,len,c,c1);
			while(*p == COMMA)
			{				
				p++;c++;
				SKIPLWS(p,len,c,c1);
				pc = new CSIPUnsupported;
				c1 = pc->Parse(p,len - c);
				if(c1 == -1)
				{
					delete pc;			
					m_nError = 30;
					return -1;
				}	
				p+=c1;
				c+=c1;
				m_Unsupporteds.push_back(pc);
				SKIPLWS(p,len,c,c1);
			}
		}
		else if(stricmp(name.c_str(),"Security-Client") == 0)
		{
		}
		else if(stricmp(name.c_str(),"Security-Server") == 0)
		{
		}
		else if(stricmp(name.c_str(),"Security-Verify") == 0)
		{
		}
		//====================
		// Mime
		//====================
		else if(stricmp(name.c_str(),"Accept") == 0)
		{//34
			CSIPAccept *pac = new CSIPAccept;
			c1 = pac->Parse(p,len-c);
			if(c1 == -1)
			{
				delete pac;
				m_nError = 34;
				return -1;
			}
			m_Accepts.push_back(pac);
			c+=c1;
			p+=c1;
			SKIPLWS(p,len,c,c1);
			while(*p == COMMA)
			{
				p++;c++;
				SKIPLWS(p,len,c,c1);		
				pac = new CSIPAccept;
				c1 = pac->Parse(p,len - c);
				if(c1 == -1)
				{
					delete pac;
					m_nError = 34;
					return -1;
				}
				m_Accepts.push_back(pac);
				c+=c1;
				p+=c1;
				SKIPLWS(p,len,c,c1);
			}
		}	
		//====================
		// GenericURIs:
		//====================
		else if(stricmp(name.c_str(),"Call-Info") == 0)
		{
			CSIPCallInfo *pac = new CSIPCallInfo;
			c1 = pac->Parse(p,len-c);
			if(c1 == -1)
			{
				delete pac;
				m_nError = 33;
				return -1;
			}
			m_CallInfos.push_back(pac);
			c+=c1;
			p+=c1;
			SKIPLWS(p,len,c,c1);
			while(*p == COMMA)
			{
				p++;c++;
				SKIPLWS(p,len,c,c1);		
				pac = new CSIPCallInfo;
				c1 = pac->Parse(p,len - c);
				if(c1 == -1)
				{
					delete pac;
					m_nError = 33;
					return -1;
				}
				m_CallInfos.push_back(pac);
				c+=c1;
				p+=c1;
				SKIPLWS(p,len,c,c1);
			}
		} 
		else if(stricmp(name.c_str(),"Alert-Info") == 0)
		{
			CSIPAlertInfo *pac = new CSIPAlertInfo;
			c1 = pac->Parse(p,len-c);
			if(c1 == -1)
			{
				delete pac;
				m_nError = 33;
				return -1;
			}
			m_AlertInfos.push_back(pac);
			c+=c1;
			p+=c1;
			SKIPLWS(p,len,c,c1);
			while(*p == COMMA)
			{
				p++;c++;
				SKIPLWS(p,len,c,c1);		
				pac = new CSIPAlertInfo;
				c1 = pac->Parse(p,len - c);
				if(c1 == -1)
				{
					delete pac;
					m_nError = 33;
					return -1;
				}
				m_AlertInfos.push_back(pac);
				c+=c1;
				p+=c1;
				SKIPLWS(p,len,c,c1);
			}
		}
		else if(stricmp(name.c_str(),"Content-Disposition") == 0)
		{
			if(m_pContentDisposition == NULL)
				m_pContentDisposition = new CSIPContentDisposition;
			c1 = m_pContentDisposition->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pContentDisposition;
				m_pContentDisposition = NULL;
				m_nError = 15;
				return -1;
			}		
			p+=c1;
			c+=c1;	
		}
		else if(stricmp(name.c_str(),"Error-Info") == 0)
		{
			CSIPErrorInfo *pac = new CSIPErrorInfo;
			c1 = pac->Parse(p,len-c);
			if(c1 == -1)
			{
				delete pac;
				m_nError = 34;
				return -1;
			}
			m_ErrorInfos.push_back(pac);
			c+=c1;p+=c1;
			SKIPLWS(p,len,c,c1);
			while(*p == COMMA)
			{
				p++;c++;
				SKIPLWS(p,len,c,c1);		
				pac = new CSIPErrorInfo;
				c1 = pac->Parse(p,len - c);
				if(c1 == -1)
				{
					delete pac;
					m_nError = 34;
					return -1;
				}
				m_ErrorInfos.push_back(pac);
				c+=c1;	p+=c1;
				SKIPLWS(p,len,c,c1);
			}
		}
		//====================
		// NameAddr:
		//====================
		
		else if(stricmp(name.c_str(),"Reply-To") == 0)
		{
			if(m_pReplyTo == NULL)
				m_pReplyTo = new CSIPReplyTo;
			c1 = m_pReplyTo->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pReplyTo;
				m_pReplyTo = NULL;
				m_nError = 40;
				return -1;
			}
			p+=c1;c+=c1;
		}
		else if(stricmp(name.c_str(),"Refer-To") == 0)
		{
		}
		else if(stricmp(name.c_str(),"Referred-By") == 0)
		{
		}
		//====================
		// String:
		//====================
		else if(stricmp(name.c_str(),"Organization") == 0)
		{
			if(m_pOrganization == NULL)
				m_pOrganization = new CSIPOrganization;
			c1 = m_pOrganization->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pOrganization;
				m_pOrganization = NULL;
				m_nError = 43;
				return -1;
			}
			p+=c1;	c+=c1;
		}
		else if(stricmp(name.c_str(),"Server") == 0)
		{
			if(m_pServer == NULL)
				m_pServer = new CSIPServer;
			c1 = m_pServer->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pServer;
				m_pServer = NULL;
				m_nError = 44;
				return -1;
			}
			p+=c1;	c+=c1;
		}
		else if(stricmp(name.c_str(),"Subject") == 0)
		{
			if(m_pSubject == NULL)
				m_pSubject = new CSIPSubject;
			c1 = m_pSubject->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pSubject;
				m_pSubject = NULL;
				m_nError = 45;
				return -1;
			}
			p+=c1;	c+=c1;
		}
		else if(stricmp(name.c_str(),"User-Agent") == 0)
		{
			if(m_pUserAgent == NULL)
				m_pUserAgent = new CSIPUserAgent;
			c1 = m_pUserAgent->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pUserAgent;
				m_pUserAgent = NULL;
				m_nError = 46;
				return -1;
			}
			p+=c1;	c+=c1;
			
		}		
		else if(stricmp(name.c_str(), "Timestamp") == 0)
		{
			if(m_pTimestamp == NULL)
				m_pTimestamp = new CSIPTimestamp;
			c1 = m_pTimestamp->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pTimestamp;
				m_pTimestamp = NULL;
				m_nError = 47;
				return -1;
			}
			p+=c1;	c+=c1;
		}
		
		else if(stricmp(name.c_str(),"Retry-After") == 0)
		{
			if(m_pRetryAfter == NULL)
				m_pRetryAfter = new CSIPRetryAfter;
			c1 = m_pRetryAfter->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pRetryAfter;
				m_pRetryAfter = NULL;
				m_nError = 49;
				return -1;
			}
			p+=c1;	c+=c1;
		}	
		else if(stricmp(name.c_str(),"Replaces") == 0)
		{
		}
		else if(stricmp(name.c_str(),"In-Reply-To") == 0)
		{
			if(m_pInReplyTo == NULL)
				m_pInReplyTo = new CSIPInReplyTo;
			c1 = m_pInReplyTo->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pInReplyTo;
				m_pInReplyTo = NULL;
				m_nError = 51;
				return -1;
			}
			p+=c1;	c+=c1;
		}
		else if(stricmp(name.c_str(),"Warning") == 0)
		{
			CSIPWarning *pc = new CSIPWarning;
			c1 = pc->Parse(p,len - c);
			if(c1 == -1)
			{
				delete pc;				
				m_nError = 57;
				return -1;
			}
			m_Warnings.push_back(pc);
			p+=c1;
			c+=c1;
			SKIPLWS(p,len,c,c1);
			while(*p == COMMA)
			{				
				p++;c++;
				SKIPLWS(p,len,c,c1);
				pc = new CSIPWarning;
				c1 = pc->Parse(p,len - c);
				if(c1 == -1)
				{
					delete pc;			
					m_nError = 57;
					return -1;
				}	
				p+=c1;
				c+=c1;
				m_Warnings.push_back(pc);
				SKIPLWS(p,len,c,c1);
			}
		}

		//====================
		// Auth:
		//====================	
		else if(stricmp(name.c_str(),"Authentication-Info") == 0)
		{
			CSIPAuthenticationInfo *pc = new CSIPAuthenticationInfo;
			c1 = pc->Parse(p,len - c);
			if(c1 == -1)
			{
				delete pc;				
				m_nError = 52;
				return -1;
			}
			m_AuthenticationInfos.push_back(pc);
			p+=c1;	c+=c1;
			SKIPLWS(p,len,c,c1);
			while(*p == COMMA)
			{				
				p++;c++;
				SKIPLWS(p,len,c,c1);
				pc = new CSIPAuthenticationInfo;
				c1 = pc->Parse(p,len - c);
				if(c1 == -1)
				{
					delete pc;			
					m_nError = 52;
					return -1;
				}	
				p+=c1;	c+=c1;
				m_AuthenticationInfos.push_back(pc);
				SKIPLWS(p,len,c,c1);
			}
		}
		else if(stricmp(name.c_str(),"Web-Address") == 0)
		{
			if(m_pWebAddress == NULL)
				m_pWebAddress = new CSIPWebAddress;
			c1 = m_pWebAddress->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pWebAddress;
				m_pWebAddress = NULL;
				m_nError = 57;
				return -1;
			}
			p+=c1;	c+=c1;
		}
		else if(stricmp(name.c_str(),"SNTP-Address") == 0)
		{
			if(m_pSNTPAddress == NULL)
				m_pSNTPAddress = new CSIPSNTPAddress;
			c1 = m_pSNTPAddress->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pSNTPAddress;
				m_pSNTPAddress = NULL;
				m_nError = 58;
				return -1;
			}
			p+=c1;	c+=c1;
		}
		else if(stricmp(name.c_str(),"Authorization") == 0)
		{
			if(m_pAuthorization == NULL)
				m_pAuthorization = new CSIPAuthorization;
			c1 = m_pAuthorization->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pAuthorization;
				m_pAuthorization = NULL;
				m_nError = 53;
				return -1;
			}		
			p+=c1;	c+=c1;
		}		
		else if(stricmp(name.c_str(),"Proxy-Authenticate") == 0)
		{
			if(m_pProxyAuthenticate == NULL)
				m_pProxyAuthenticate = new CSIPProxyAuthenticate;
			c1 = m_pProxyAuthenticate->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pProxyAuthenticate;
				m_pProxyAuthenticate = NULL;
				m_nError = 54;
				return -1;
			}		
			p+=c1;c+=c1;
		}		
		else if(stricmp(name.c_str(),"Proxy-Authorization") == 0)
		{
			if(m_pProxyAuthorization == NULL)
				m_pProxyAuthorization = new CSIPProxyAuthorization;
			c1 = m_pProxyAuthorization->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pProxyAuthorization;
				m_pProxyAuthorization = NULL;
				m_nError = 55;
				return -1;
			}		
			p+=c1;c+=c1;
		}
		else if(stricmp(name.c_str(),"Www-Authenticate") == 0)
		{
			if(m_pWWWAuthenticate == NULL)
				m_pWWWAuthenticate = new CSIPWWWAuthenticate;
			c1 = m_pWWWAuthenticate->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pWWWAuthenticate;
				m_pWWWAuthenticate = NULL;
				m_nError = 56;
				return -1;
			}		
			p+=c1;	c+=c1;
		}		
		else if(stricmp(name.c_str(),"Scale") == 0)
		{
			if(m_pScale == NULL)
				m_pScale = new CSIPScale(0.0);
			c1 = m_pScale->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pScale;
				m_pScale = NULL;
				m_nError = 70;
				return -1;
			}
			p+=c1;c+=c1;
		}
		else if(stricmp(name.c_str(),"Seek") == 0)
		{
			if(m_pSeek == NULL)
				m_pSeek = new CSIPSeek(0);
			c1 = m_pSeek->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pSeek;
				m_pSeek = NULL;
				m_nError = 71;
				return -1;
			}
			p+=c1;c+=c1;
		}
		else if(stricmp(name.c_str(), "FileName") == 0)
		{
			if(m_pFileName == NULL)
				m_pFileName = new CSIPFileName;
			c1 = m_pFileName->Parse(p,len - c);
			if(c1 == -1)
			{
				delete m_pFileName;
				m_pFileName = NULL;
				m_nError = 57;
				return -1;
			}
			p+=c1;	c+=c1;
		}
		else
		{//unkown header
			CSIPUnknown *punknown = new CSIPUnknown;
			c1 = punknown->Parse(p,len - c);
			if(c1 == -1)
			{
				delete punknown;
				m_nError = 200;
				return -1;
			}
			p+=c1;
			c+=c1;
			m_UnknownHeaders.push_back(punknown);
		}
		
		if(strncmp(p,"\r\n",2))
		{
			m_nError = 1;
			return -1;
		}
		//skip CRLF
		p+=2;
		c+=2;
		if(c >= len)
		{
			m_nError = -1;
			return -1;
		}
		//is end of message headers
		if(strncmp(p,"\r\n",2) == 0)
		{
			p+=2;
			c += 2;
			if(c == len)
			{				
				return c;
			}
			else if(c > len)
				return -1;
			break;
		}
	}
	
	if(m_pContentLength && (m_pContentLength->GetContentLength() > 0 || m_pContentLength->GetContentLength() == -1))
	{
		if(m_pContentLength->GetContentLength() == -1 && p && len - c>0)
		{
			if(m_pContentType && stricmp(m_pContentType->GetType().c_str(),"Application") == 0 && 
				stricmp(m_pContentType->GetSubType().c_str(),"SDP") == 0)
			{
				m_pContent = new CSDPContent;
				m_pContent->SetContent(p,len - c);
			}
			else
			{
				m_pContent = new CSIPContent;
				m_pContent->SetContent(p,len - c);
			}
			p+=(len - c);
			c+=(len - c);
		}
		else if(p && len - c == m_pContentLength->GetContentLength())
		{
			if(m_pContentType && stricmp(m_pContentType->GetType().c_str(),"Application") == 0 && 
				stricmp(m_pContentType->GetSubType().c_str(),"SDP") == 0)
			{
				m_pContent = new CSDPContent;
				m_pContent->SetContent(p,m_pContentLength->GetContentLength());
			}
			else
			{
				m_pContent = new CSIPContent;
				m_pContent->SetContent(p,m_pContentLength->GetContentLength());
			}
			p+=m_pContentLength->GetContentLength();
			c+=m_pContentLength->GetContentLength();
		}
	}	
	
	timeval tv;
	gettimeofday(&tv, NULL);
#ifdef PERFORMANCE_TEST
    printf("SIP Parse take %lld us.\n", tv.tv_sec * 1000 * 1000  +  tv.tv_usec - m_usProduceTime);
#endif
    m_usProduceTime = tv.tv_sec * 1000 * 1000  +  tv.tv_usec;
	return c;
}

mystring CSIPMessage::Encoding()
{
	mystring en;
	if(m_pStatusLine)
	{
		en = m_pStatusLine->Encode();
		en += "\r\n";
	}
	if(m_pRequestLine)
	{		
		en = m_pRequestLine->Encode();
		en += "\r\n";
	}
	if(m_Vias.size() > 0)
	{	
		for(std::list<CSIPVia *>::const_iterator i=m_Vias.begin();i!=m_Vias.end();i++)
		{
			en += (*i)->Encode();
			en += "\r\n";
		}
	}
	
	if(m_pTo)
	{
		en += m_pTo->Encode();
		en +="\r\n";
	}
	if(m_pFrom)
	{
		en += m_pFrom->Encode();
		en += "\r\n";
	}
	if(m_Routes.size() > 0)
	{
		for(CSIPRoutesItem ri = m_Routes.begin();ri != m_Routes.end();ri++)
		{
			en += (*ri)->Encode();
			en += "\r\n";
		}
	}

	if(m_RecordRoutes.size() > 0)
	{
		for(CSIPRoutesItem ri = m_RecordRoutes.begin();ri != m_RecordRoutes.end();ri++)
		{
			en += (*ri)->Encode();
			en += "\r\n";
		}
	}

	if(m_pCallID)
	{
		en += m_pCallID->Encode();
		en += "\r\n";
	}
	if(m_pSequence)
	{
		en += m_pSequence->Encode();
		en += "\r\n";
	}
	if(m_pTranslate)
	{
		en += m_pTranslate->Encode();
		en += "\r\n";
	}
	if(m_Contacts.size())
	{
		en += "Contact: ";
		int c = 0;
		for(std::list<CSIPContact *>::const_iterator i=m_Contacts.begin();i!=m_Contacts.end();i++)
		{
			if(c)
				en += ",";
			en += (*i)->EncodeNoName();
			c++;
		}

	//	en += m_Contact->Encode();
		en += "\r\n";
	}
	if(m_pAuthorization)
	{
		en += m_pAuthorization->Encode();
		en += "\r\n";
	}

	if(m_pProxyAuthorization)
	{
		en += m_pProxyAuthorization->Encode();
		en += "\r\n";
	}
	if(m_pProxyAuthenticate)
	{
		en += m_pProxyAuthenticate->Encode();
		en += "\r\n";
	}
	if(m_pWWWAuthenticate)
	{
		en += m_pWWWAuthenticate->Encode();
		en += "\r\n";
	}
	if(m_pExpires)
	{
		en += m_pExpires->Encode();
		en += "\r\n";
	}
	if(m_pMinExpires)
	{
		en += m_pMinExpires->Encode();
		en += "\r\n";
	}
	if(m_pUserAgent)
	{
		en += m_pUserAgent->Encode();
		en += "\r\n";
	}
	if(m_pEvent)
	{
		en += m_pEvent->Encode();
		en += "\r\n";
	}
	if(m_AllowEvents.size()>0)
	{
		en += "Allow-Events: ";	
		int c = 0;
		for(std::list<CSIPAllowEvents *>::const_iterator i=m_AllowEvents.begin();i!=m_AllowEvents.end();i++)
		{
			if(c)
				en += ",";
			en += (*i)->EncodeNoName();
			c++;
		}

	//	en += m_AllowEvents->Encode();
		en += "\r\n";
	
	}
	if(m_pMaxForwards)
	{
		en += m_pMaxForwards->Encode();
		en += "\r\n";
	}
	if(m_pScale)
	{
		en += m_pScale->Encode();
		en += "\r\n";
	}
	if(m_pSeek)
	{
		en += m_pSeek->Encode();
		en += "\r\n";
	}
	if(m_NATAddresses.size() > 0)
	{
		en += "NATAddress: ";
		int c = 0;
		for(std::list<CSIPNATAddress *>::const_iterator i=m_NATAddresses.begin();i!=m_NATAddresses.end();i++)
		{
			if(c)
				en += ",";
			en += (*i)->EncodeNoName();		
		}
		en += "\r\n";	
	}
	if(m_Allows.size()>0)
	{
		en += "Allow: ";
		int c = 0;
		for(std::list<CSIPAllowEvents *>::const_iterator i=m_AllowEvents.begin();i!=m_AllowEvents.end();i++)
		{
			if(c)
				en += ",";
			en += (*i)->EncodeNoName();		
		}
		en += "\r\n";	
	}
	
	if(m_pSubscriptionState)
	{
		en += m_pSubscriptionState->Encode();
		en += "\r\n";
	}
	if(m_Requires.size())
	{
		en += "Require: ";
		int c = 0;
		for(std::list<CSIPRequire *>::const_iterator i=m_Requires.begin();i!=m_Requires.end();i++)
		{
			if(c)
				en += ",";
			en += (*i)->EncodeNoName();		
		}
		en += "\r\n";	
	}

	

	if(m_pDate)
	{
		en += m_pDate->Encode();
		en += "\r\n";
	}	
	if(m_pMIMEVersion)
	{
		en += m_pMIMEVersion->Encode();
		en += "\r\n";
	}
	
	if(m_Accepts.size()>0)
	{
		en += "Accept: ";
		int c = 0;
		for(std::list<CSIPAccept *>::const_iterator i=m_Accepts.begin();i!=m_Accepts.end();i++)
		{
			if(c)
				en == ",";
			en += (*i)->EncodeNoName();
		
		}
		en += "\r\n";
	}
//#ifdef PC_CLIENT
	if(m_AuthenticationInfos.size() > 0)
	{
		en += "Authentication-Info: ";
		int c = 0;
		for(std::list<CSIPAuthenticationInfo *>::const_iterator i=m_AuthenticationInfos.begin();i!=m_AuthenticationInfos.end();i++)
		{
			if(c)
				en += ",";
			en += (*i)->EncodeNoName();
		}
		en += "\r\n";	
	}
	if(m_pServer)
	{
		en += m_pServer->Encode();
		en += "\r\n";
	}
	if(m_Unsupporteds.size()>0)
	{
		en += "Unsupported: ";
		int c = 0;
		for(std::list<CSIPUnsupported *>::const_iterator i=m_Unsupporteds.begin();i!=m_Unsupporteds.end();i++)
		{
			if(c)
				en == ",";
			en += (*i)->EncodeNoName();
		
		}
		en += "\r\n";
	}

	
	if(m_ProxyRequires.size())
	{
		en += "Proxy-Require: ";
		int c = 0;
		for(std::list<CSIPProxyRequire *>::const_iterator i=m_ProxyRequires.begin();i!=m_ProxyRequires.end();i++)
		{
			if(c)
				en += ",";
			en += (*i)->EncodeNoName();		
		}
		en += "\r\n";	
	}
	
	if(m_pRetryAfter)
	{
		en += m_pRetryAfter->Encode();
		en += "\r\n";
	}
	
	if(m_pSubject)
	{
		en += m_pSubject->Encode();
		en += "\r\n";
	}
	if(m_pInReplyTo)
	{
		en += m_pInReplyTo->Encode();
		en += "\r\n";
	}
	if(m_pOrganization)
	{
		en += m_pOrganization->Encode();
		en += "\r\n";
	}
	if(m_pReplyTo)
	{
		en += m_pReplyTo->Encode();
		en += "\r\n";
	}
	if(m_pTimestamp)
	{
		en += m_pTimestamp->Encode();
		en += "\r\n";
	}
	
	if(m_ErrorInfos.size() > 0)
	{
		en += "Error-Info: ";
		int c = 0;
		for(std::list<CSIPErrorInfo *>::const_iterator i=m_ErrorInfos.begin();i!=m_ErrorInfos.end();i++)
		{
			if(c)
				en += ",";
			en += (*i)->EncodeNoName();
		}
		en += "\r\n";	
	}

	if(m_CallInfos.size() > 0)
	{
		en += "Call-Info: ";
		int c = 0;
		for(std::list<CSIPCallInfo *>::const_iterator i=m_CallInfos.begin();i!=m_CallInfos.end();i++)
		{
			if(c)
				en += ",";
			en += (*i)->EncodeNoName();
		}
		en += "\r\n";	
	}
	if(m_Supporteds.size() > 0)
	{
		en += "Supported: ";
		int c = 0;
		for(std::list<CSIPSupported *>::const_iterator i=m_Supporteds.begin();i!=m_Supporteds.end();i++)
		{
			if(c)
				en == ",";
			en += (*i)->EncodeNoName();
		
		}
		en += "\r\n";
	}
	if(m_pPriority)
	{
		en += m_pPriority->Encode();
		en += "\r\n";
	}
	if(m_Warnings.size() > 0)
	{
		en += "Warning: ";
		int c = 0;
		for(std::list<CSIPWarning *>::const_iterator i=m_Warnings.begin();i!=m_Warnings.end();i++)
		{
			if(c)
				en += ",";
			en += (*i)->EncodeNoName();		
		}
		en += "\r\n";	
	}
	if(m_pWebAddress)
	{
		en += m_pWebAddress->Encode();
		en += "\r\n";
	}
	if(m_pSNTPAddress)
	{
		en += m_pSNTPAddress->Encode();
		en += "\r\n";
	}
	if(m_pFileName)
	{
		en += m_pFileName->Encode();
		en +="\r\n";
	}
//#endif
	if(m_UnknownHeaders.size() > 0)
	{
		for(std::list<CSIPUnknown *>::const_iterator i=m_UnknownHeaders.begin();i!=m_UnknownHeaders.end();i++)
		{
			en += (*i)->Encode();
			en += "\r\n";
		}
	}
	if(m_pContent && m_pContentType)
	{
		en += m_pContentType->Encode();
		en += "\r\n";
	}
	if(m_pContent)
	{
		char buf[24];
		mystring content = m_pContent->Encode();
		sprintf(buf,"%d",content.length());
		en += "Content-Length: ";
		en += buf;
		en += "\r\n";
		en += "\r\n";
		en += content;
	}
	else
	{
		en +="Content-Length: 0\r\n";
		en += "\r\n";
	}
	
	return en;
}
void CSIPMessage::RemoveContent()
{
	if(m_pContent)
	{
		delete m_pContent;
		m_pContent = NULL;
	}
	if(m_pContentType)
	{
		delete m_pContentType;
		m_pContentType = NULL;
	}
}
void CSIPMessage::Clear()
{
	m_nType = 0;
	m_strTransactionID = "";
	if(m_pRequestLine)
	{
		delete m_pRequestLine;
		m_pRequestLine = NULL;
	}
	if(m_pStatusLine)
	{
		delete m_pStatusLine;
		m_pStatusLine = NULL;
	}
	if(m_pCallID)
	{
		delete m_pCallID;
		m_pCallID = NULL;
	}
	if(m_pSequence)
	{
		delete m_pSequence;
		m_pSequence = NULL;
	}	
	if(m_pTo)
	{
		delete m_pTo;
		m_pTo = NULL;
	}
	if(m_pFrom)
	{
		delete m_pFrom;
		m_pFrom = NULL;
	}
	CSIPRequire *pr;
	while(m_Requires.empty() == false)
	{
		pr = m_Requires.front();
		m_Requires.pop_front();
		delete pr;	
	}
	if(m_pScale)
	{
		delete m_pScale;
		m_pScale = NULL;
	}
	if(m_pSeek)
	{
		delete m_pSeek;
		m_pSeek = NULL;
	}
	
	if(m_pProxyAuthenticate)
	{
		delete m_pProxyAuthenticate;
		m_pProxyAuthenticate = NULL;
	}
	if(m_pProxyAuthorization)
	{
		delete m_pProxyAuthorization;
		m_pProxyAuthorization = NULL;
	}
	if(m_pMIMEVersion)
	{
		delete m_pMIMEVersion;
		m_pMIMEVersion = NULL;
	}
	if(m_pExpires)
	{
		delete m_pExpires;
		m_pExpires = NULL;
	}
	if(m_pMinExpires)
	{
		delete m_pMinExpires;
		m_pMinExpires = NULL;
	}
	if(m_pMaxForwards)
	{
		delete m_pMaxForwards;
		m_pMaxForwards = NULL;
	}

	
	if(m_pContentLength)
	{
		delete m_pContentLength;
		m_pContentLength = NULL;
	}
	if(m_pContentType)
	{
		delete m_pContentType;
		m_pContentType = NULL;
	}
	
	CSIPContentEncoding *pce;
	while(m_ContentEncodings.empty() == false)
	{
		pce = m_ContentEncodings.front();
		m_ContentEncodings.pop_front();
		delete pce;		
	}
	CSIPContentLanguage *pcl;
	while(m_ContentLanguages.empty() == false)
	{
		pcl = m_ContentLanguages.front();
		m_ContentLanguages.pop_front();
		delete pcl;	
	}
	
	CSIPRoute *proute;
	while(!m_RecordRoutes.empty())
	{
		proute = m_RecordRoutes.front();
		m_RecordRoutes.pop_front();
		delete proute;		
	}
	
	while(!m_Routes.empty())
	{
		proute = m_Routes.front();
		m_Routes.pop_front();
		delete proute;		
	}
	if(m_pContent)
	{
		delete m_pContent;
		m_pContent = NULL;
	}
	CSIPAcceptEncoding *pae;
	while(!m_AcceptEncodings.empty())
	{
		pae = m_AcceptEncodings.front();
		m_AcceptEncodings.pop_front();
		delete pae;		
	}
	CSIPAcceptLanguage *pal;
	while(!m_AcceptLanguages.empty())
	{
		pal = m_AcceptLanguages.front();
		m_AcceptLanguages.pop_front();
		delete pal;
	}
	CSIPContact *pna;
	while(!m_Contacts.empty())
	{
		pna = m_Contacts.front();
		m_Contacts.pop_front();
		delete pna;
	}
	CSIPNATAddress *pnata;
	while(!m_NATAddresses.empty())
	{
		pnata = m_NATAddresses.front();
		m_NATAddresses.pop_front();
		delete pnata;
	}
	if(m_pSNTPAddress)
	{
		delete m_pSNTPAddress;
		m_pSNTPAddress = NULL;
	}
//#ifdef PC_CLIENT
	CSIPAuthenticationInfo *pai;
	while(!m_AuthenticationInfos.empty())
	{
		pai = m_AuthenticationInfos.front();
		m_AuthenticationInfos.pop_front();
		delete pai;
	}
	if(m_pContentDisposition)
	{
		delete m_pContentDisposition;
		m_pContentDisposition = NULL;
	}
	if(m_pRetryAfter)
	{
		delete m_pRetryAfter;
		m_pRetryAfter = NULL;
	}
	CSIPErrorInfo *pei;
	while(m_ErrorInfos.empty() == false)
	{
		pei = m_ErrorInfos.front();
		m_ErrorInfos.pop_front();
		delete pei;
	}

	CSIPUnsupported *pusp;
	if(m_Unsupporteds.empty() == false)
	{
		pusp = m_Unsupporteds.front();
		m_Unsupporteds.pop_front();
		delete pusp;
	
	}
	if(m_pPriority)
	{
		delete m_pPriority;
		m_pPriority = NULL;
	}
	CSIPSupported *psp;
	while(m_Supporteds.empty() == false)
	{
		psp = m_Supporteds.front();
		m_Supporteds.pop_front();
		delete psp;	
	}
	CSIPCallInfo *pci;
	while(!m_CallInfos.empty())
	{
		pci = m_CallInfos.front();
		m_CallInfos.pop_front();
		delete pci;
	}
	if(m_pReplyTo)
	{
		delete m_pReplyTo;
		m_pReplyTo = NULL;
	}
	if(m_pOrganization)
	{
		delete m_pOrganization;
		m_pOrganization = NULL;
	}
	if(m_pSubject)
	{
		delete m_pSubject;
		m_pSubject = NULL;
	}
	if(m_pServer)
	{
		delete m_pServer;
		m_pServer = NULL;
	}
	if(m_pTranslate)
	{
		delete m_pTranslate;
		m_pTranslate = NULL;
	}
	while(m_Accepts.empty() == false)
	{
		delete m_Accepts.front();
		m_Accepts.pop_front();
	}
	if(m_pUserAgent)
	{
		delete m_pUserAgent;
		m_pUserAgent = NULL;
	}
	if(m_pFileName)
	{
		delete m_pFileName;
		m_pFileName = NULL;
	}
	if(m_pDate)
	{
		delete m_pDate;
		m_pDate = NULL;
	}
	if(m_pAuthorization)
	{
		delete m_pAuthorization;
		m_pAuthorization = NULL;
	}
	if(m_pWWWAuthenticate)
	{
		delete m_pWWWAuthenticate;
		m_pWWWAuthenticate = NULL;
	}
	if(m_pTimestamp)
	{
		delete m_pTimestamp;
		m_pTimestamp = NULL;
	}
	CSIPVia *pvia;
	while(m_Vias.empty() == false)
	{
		pvia = m_Vias.front();
		m_Vias.pop_front();
		delete pvia;		
	}

	if(m_pEvent)
	{
		delete m_pEvent;
		m_pEvent = NULL;
	}
	CSIPAllowEvents *pevts;
	while(m_AllowEvents.empty() == false)
	{
		pevts = m_AllowEvents.front();
		m_AllowEvents.pop_front();
		delete pevts;	
	}
	CSIPWarning *pwn;
	while(m_Warnings.empty() == false)
	{
		pwn = m_Warnings.front();
		m_Warnings.pop_front();
		delete pwn;
	}
	CSIPProxyRequire *ppr;
	while(m_ProxyRequires.empty() == false)
	{
		ppr = m_ProxyRequires.front();
		m_ProxyRequires.pop_front();
		delete ppr;	
	}
	if(m_pWebAddress)
	{
		delete m_pWebAddress;
		m_pWebAddress = NULL;
	}
//#endif
	CSIPUnknown *punknown;
	while(!m_UnknownHeaders.empty())
	{
		punknown = m_UnknownHeaders.front();	
		m_UnknownHeaders.pop_front();
		delete punknown;		
	}
	if(m_pSubscriptionState)
	{
		delete m_pSubscriptionState;
		m_pSubscriptionState = NULL;
	}
}

void CSIPMessage::Init()
{
	m_nType = 0;
	//m_sTransactionID = "";
	
	m_pProxyAuthorization = NULL;

	m_pScale = NULL;
	m_pSeek = NULL;
	m_pProxyAuthenticate = NULL;		
	m_pRequestLine = NULL;
	m_pStatusLine = NULL;
	m_pCallID = NULL;
	m_pTo = NULL;
	m_pFrom = NULL;
	m_pMaxForwards = NULL;
	m_pSequence = NULL;
	m_pFileName = NULL;
	m_pContentLength = NULL;
	
	m_pContentType = NULL;
	m_pExpires = NULL;
	m_pMinExpires = NULL;
	m_pContent = NULL;
	//m_pContact = NULL;
	m_pTranslate = NULL;
	
	m_pAuthorization = NULL;
	m_pWWWAuthenticate = NULL;
	m_pMIMEVersion = NULL;
	m_pEvent = NULL;
	m_pDate = NULL;
	m_pUserAgent = NULL;	
	m_pSubscriptionState = NULL;
//#ifdef PC_CLIENT
	m_pWebAddress = NULL;
	m_pSNTPAddress = NULL;
	m_pTimestamp = NULL;
	m_pContentDisposition = NULL;
	m_pServer = NULL;
	m_pPriority = NULL;
	m_pInReplyTo = NULL;  
	m_pReplyTo = NULL;
	m_pOrganization = NULL;	
	m_pSubject = NULL;	
	m_pRetryAfter = NULL;
//#endif

     //yb added 20100203{
    m_usProduceTime = 0; //the time sip is created
    m_usRequestTime = 0;
    m_pTransaction = NULL;
    //yb added 20100203}
}
MethodTypes CSIPMessage::GetMethod()const
{
	if(IsRequest() == false)
	{
		if(m_pSequence)
			return m_pSequence->GetMethod();
	}
	else 
	{
		if(m_pRequestLine)
			return m_pRequestLine->GetMethod();
	}
	return UNKNOWN;
}

CSIPMaxForwards &CSIPMessage::MaxForwards()
{
	if(m_pMaxForwards == NULL)	
		m_pMaxForwards = new CSIPMaxForwards;

	return *m_pMaxForwards;
}
CSIPSequence &CSIPMessage::Sequence()
{
	if(m_pSequence == NULL)
		m_pSequence = new CSIPSequence;
	return *m_pSequence;
}
CSIPSequence &CSIPMessage::CSeq()
{
	if(m_pSequence == NULL)
		m_pSequence = new CSIPSequence;
	return *m_pSequence;
}
CSIPAuthorization &CSIPMessage::Authorization()
{
	if(m_pAuthorization == NULL)
		m_pAuthorization = new CSIPAuthorization;
	return *m_pAuthorization;
}

CSIPProxyAuthorization &CSIPMessage::ProxyAuthorization()
{
	if(m_pProxyAuthorization == NULL)
		m_pProxyAuthorization = new CSIPProxyAuthorization;
	return *m_pProxyAuthorization;
}

CSIPWWWAuthenticate &CSIPMessage::WWWAuthenticate()
{
	if(m_pWWWAuthenticate == NULL)
		m_pWWWAuthenticate = new CSIPWWWAuthenticate;
	return *m_pWWWAuthenticate;
}

CSIPProxyAuthenticate &CSIPMessage::ProxyAuthenticate()
{
	if(m_pProxyAuthenticate == NULL)
		m_pProxyAuthenticate = new CSIPProxyAuthenticate;
	return *m_pProxyAuthenticate;
}


CSIPCallID &CSIPMessage::CallId()
{
	if(m_pCallID == NULL)
		m_pCallID = new CSIPCallID;
	return *m_pCallID;
}
CSIPRequestLine &CSIPMessage::RequestLine()
{
	if(m_pRequestLine == NULL)
		m_pRequestLine = new CSIPRequestLine;
	return *m_pRequestLine;
}
CSIPStatusLine &CSIPMessage::StatusLine()
{
	if(m_pStatusLine == NULL)
		m_pStatusLine = new CSIPStatusLine;
	return *m_pStatusLine;
}

CSIPTo &CSIPMessage::To()
{
	if(m_pTo == NULL)
		m_pTo = new CSIPTo();
	return *m_pTo;
}
CSIPFrom &CSIPMessage::From()
{
	if(m_pFrom == NULL)
		m_pFrom = new CSIPFrom();
	return *m_pFrom;
}
CSIPTranslate &CSIPMessage::Translate()
{
	if(m_pTranslate == NULL)
		m_pTranslate = new CSIPTranslate;
	return *m_pTranslate;
}
CSIPExpires &CSIPMessage::Expires()
{
	if(m_pExpires == NULL)
		m_pExpires = new CSIPExpires;
	return *m_pExpires;
}
CSIPMinExpires &CSIPMessage::MinExpires()
{
	if(m_pMinExpires == NULL)
		m_pMinExpires = new CSIPMinExpires;
	return *m_pMinExpires;
}
CSIPEvent &CSIPMessage::Event()
{
	if(m_pEvent == NULL)
		m_pEvent = new CSIPEvent;
	return *m_pEvent;
}

CSIPUserAgent &CSIPMessage::UserAgent()
{
	if(m_pUserAgent == NULL)
		m_pUserAgent = new CSIPUserAgent;
	return *m_pUserAgent;
}

CSIPScale &CSIPMessage::Scale()
{
	if(m_pScale == NULL)
		m_pScale = new CSIPScale(0.0);
	return *m_pScale;
}
CSIPSeek &CSIPMessage::Seek()
{
	if(m_pSeek == NULL)
		m_pSeek = new CSIPSeek(0);
	return *m_pSeek;
}
CSIPContentType &CSIPMessage::ContentType()
{
	if(m_pContentType == NULL)
		m_pContentType = new CSIPContentType;
	return *m_pContentType;
}
CSIPContentLength &CSIPMessage::ContentLength()
{
	if(m_pContentLength == NULL)
		m_pContentLength = new CSIPContentLength;
	return *m_pContentLength;
}
CSIPContent &CSIPMessage::Content()
{
	if(m_pContent == NULL)
	{
		if(m_pContentType)
		{
			if(stricmp(m_pContentType->GetType().c_str() ,"application") == 0 && stricmp(m_pContentType->GetSubType().c_str(),"sdp") == 0)
			{
				m_pContent = new CSDPContent;
			}
			else
			{
				m_pContent = new CSIPContent;
			}
		}
		else
			m_pContent = new CSIPContent;
	}
	return *m_pContent;
}
//#ifdef PC_CLIENT
CSIPWebAddress &CSIPMessage::WebAddress()
{
	if(m_pWebAddress == NULL)
		m_pWebAddress = new CSIPWebAddress;
	return *m_pWebAddress;
}
CSIPSNTPAddress &CSIPMessage::SNTPAddress()
{
	if(m_pSNTPAddress == NULL)
		m_pSNTPAddress = new CSIPSNTPAddress;
	return *m_pSNTPAddress;
}
CSIPFileName &CSIPMessage::FileName()
{
	if(m_pFileName == NULL)
		m_pFileName = new CSIPFileName;
	return *m_pFileName;
}

CSIPSubscriptionState &CSIPMessage::SubscriptionState()
{
	if(m_pSubscriptionState == NULL)
		m_pSubscriptionState = new CSIPSubscriptionState;
	return *m_pSubscriptionState;
}

CSIPDate &CSIPMessage::Date()
{
	if(m_pDate == NULL)
		m_pDate = new CSIPDate;
	return *m_pDate;
}

CSIPServer &CSIPMessage::Server()
{
	if(m_pServer == NULL)
		m_pServer = new CSIPServer;
	return *m_pServer;
}

CSIPContentDisposition &CSIPMessage::ContentDisposition()
{
	if(m_pContentDisposition == NULL)
		m_pContentDisposition = new CSIPContentDisposition;
	return *m_pContentDisposition;
}
CSIPTimestamp &CSIPMessage::Timestamp()
{
	if(m_pTimestamp == NULL)
		m_pTimestamp = new CSIPTimestamp;
	return *m_pTimestamp;
}

CSIPSubject &CSIPMessage::Subject()
{
	if(m_pSubject == NULL)
		m_pSubject = new CSIPSubject;
	return *m_pSubject;
}

//#endif

CSIPMessage& CSIPMessage::operator=(const CSIPMessage& other)
{   	
	Clear();
	m_nType = other.m_nType;
	while(false == this->m_DestIPList.empty())
	{
		this->m_DestIPList.pop_front();
	}
	for(list<DestinationInfo>::const_iterator cip = other.m_DestIPList.begin();cip != other.m_DestIPList.end();cip++)
	{
		m_DestIPList.push_back(*cip);
	}	
	if(other.m_pRequestLine)
		m_pRequestLine = new CSIPRequestLine(*other.m_pRequestLine);

	if(other.m_pStatusLine)
		m_pStatusLine = new CSIPStatusLine(*other.m_pStatusLine);

	if(other.m_pCallID)
		m_pCallID = new CSIPCallID(*other.m_pCallID);
	

	if(other.m_pSequence)
		m_pSequence = new CSIPSequence(*other.m_pSequence);

	if(other.m_pTo)
		m_pTo = new CSIPTo(*other.m_pTo);


	if(other.m_pFrom)
		m_pFrom = new CSIPFrom(*other.m_pFrom);
	
	if(other.m_pExpires)
		m_pExpires = new CSIPExpires(*other.m_pExpires);

	if(other.m_pMinExpires)
		m_pMinExpires = new CSIPMinExpires(*other.m_pMinExpires);

	if(other.m_pMaxForwards)
		m_pMaxForwards = new CSIPMaxForwards(*other.m_pMaxForwards);

	if(other.m_pScale)
		m_pScale = new CSIPScale(other.m_pScale->GetScale());
	if(other.m_pSeek)
		m_pSeek = new CSIPSeek(other.m_pSeek->GetPos());

	COPYOBJECT(CSIPContentEncoding,m_ContentEncodings,other,pce,cei);

	COPYOBJECT(CSIPContentLanguage,m_ContentLanguages,other,pcl,cli);

	if(other.m_pContentLength)
		m_pContentLength = new CSIPContentLength(*other.m_pContentLength);
	
	if(other.m_pContentType)
		m_pContentType = new CSIPContentType(*other.m_pContentType);
	
	if(other.m_pContent)
	{
		if(m_pContentType && stricmp(m_pContentType->GetType().c_str(),"application") == 0 &&
			stricmp(m_pContentType->GetSubType().c_str(),"sdp") == 0)
			m_pContent = new CSDPContent((CSDPContent &)*other.m_pContent);
		else
			m_pContent = new CSIPContent(*other.m_pContent);
	}
	else if(m_pContent)
	{
		delete m_pContent;
		m_pContent = NULL;
	}

	
	CSIPAccept *pac;
	if(other.m_Accepts.size() > 0)
	{
		while(m_Accepts.empty() == false)
		{
			pac = m_Accepts.front();
			m_Accepts.pop_front();
			delete pac;
		}
		for(std::list<CSIPAccept *>::const_iterator i = other.m_Accepts.begin();i!=other.m_Accepts.end();i++)
		{
			m_Accepts.push_back(new CSIPAccept(**i));
		}
	}
	else
	{		
		while(!m_Accepts.empty())
		{
			pac = m_Accepts.front();	
			m_Vias.pop_front();
			delete pac;		
		}		
	}
//#ifdef PC_CLIENT
	if(other.m_pContentDisposition)
	{
		if(m_pContentDisposition == NULL)
			m_pContentDisposition = new CSIPContentDisposition;
		*m_pContentDisposition = *other.m_pContentDisposition;
	}
	else if(m_pContentDisposition)
	{
		delete m_pContentDisposition;
		m_pContentDisposition = NULL;
	}
	if(other.m_pPriority)
	{
		if(m_pPriority == NULL)
			m_pPriority = new CSIPPriority;
		*m_pPriority = *other.m_pPriority;
	}
	else if(m_pPriority)
	{
		delete m_pPriority;
		m_pPriority = NULL;
	}

	COPYOBJECT(CSIPErrorInfo,m_ErrorInfos,other,pei,peii);
	COPYOBJECT(CSIPCallInfo,m_CallInfos,other,pci,pcii);
	
	if(other.m_pRetryAfter)
	{
		if(m_pRetryAfter == NULL)
			m_pRetryAfter = new CSIPRetryAfter;
		*m_pRetryAfter = *other.m_pRetryAfter;
	}
	else if(m_pRetryAfter)
	{
		delete m_pRetryAfter;
		m_pRetryAfter = NULL;
	}
	COPYOBJECT(CSIPUnsupported,m_Unsupporteds,other,pusp,usi);

	COPYOBJECT(CSIPSupported,m_Supporteds,other,psp,spi);

	COPYOBJECT(CSIPWarning,m_Warnings,other,pwn,pwni);


	if(other.m_pSubject)
	{
		if(m_pSubject == NULL)
			m_pSubject = new CSIPSubject;
		*m_pSubject = *other.m_pSubject;
	}
	else if(this->m_pSubject)
	{
		delete m_pSubject;
		m_pSubject = NULL;
	}
	if(other.m_pInReplyTo)
	{
		if(m_pInReplyTo == NULL)
			m_pInReplyTo = new CSIPInReplyTo;
		*m_pInReplyTo = *other.m_pInReplyTo;
	}
	else if(this->m_pInReplyTo)
	{
		delete m_pInReplyTo;
		m_pInReplyTo = NULL;
	}
	COPYOBJECT(CSIPProxyRequire,m_ProxyRequires,other,ppr,pri);

	COPYOBJECT(CSIPAuthenticationInfo,m_AuthenticationInfos,other,pai,paii);
	if(other.m_pWebAddress)
	{
		if(m_pWebAddress == NULL)
			m_pWebAddress = new CSIPWebAddress(*other.m_pWebAddress);
		else
		{
			m_pWebAddress->Clear();
			*m_pWebAddress = *other.m_pWebAddress;
		}
	}
	else if(m_pWebAddress)
	{
		delete m_pWebAddress;
		m_pWebAddress = NULL;
	}

	if(other.m_pSNTPAddress)
	{
		if(m_pSNTPAddress == NULL)
			m_pSNTPAddress = new CSIPSNTPAddress(*other.m_pSNTPAddress);
		else
		{
			m_pSNTPAddress->Clear();
			*m_pSNTPAddress = *other.m_pSNTPAddress;
		}
	}
	else if(m_pSNTPAddress)
	{
		delete m_pSNTPAddress;
		m_pSNTPAddress = NULL;
	}


	if(other.m_pFileName)
	{
		if(m_pFileName == NULL)
		{
			m_pFileName = new CSIPFileName(*other.GetFileName());
		}
		else
		{
			m_pFileName->Clear();
			*m_pFileName = *other.GetFileName();
		}
	}
	else if(m_pFileName)
	{
		delete m_pFileName;
		m_pFileName = NULL;
	}
//#endif
	if(other.m_pEvent)
		m_pEvent = new CSIPEvent(*other.m_pEvent);
	COPYOBJECT(CSIPNATAddress,m_NATAddresses,other,pnata,pnatai);

	COPYOBJECT(CSIPAllow,m_Allows,other,pallow,ai);

	COPYOBJECT(CSIPAllowEvents,m_AllowEvents,other,paevts,ei);

	COPYOBJECT(CSIPContact,m_Contacts,other,pcts,ci);
	

	if(other.m_pUserAgent)
	{
		if(m_pUserAgent == NULL)
			m_pUserAgent = new CSIPUserAgent(*other.m_pUserAgent);
		else
		{
			m_pUserAgent->Clear();
			*m_pUserAgent = *other.m_pUserAgent;
		}
	}
	else if(m_pUserAgent)
	{
		delete m_pUserAgent;
		m_pUserAgent = NULL;
	}
	
	COPYOBJECT(CSIPRoute,m_Routes,other,prt,prti);
	COPYOBJECT(CSIPRoute,m_RecordRoutes,other,prrt,prrti);


	CSIPVia *pvia;
	if(other.m_Vias.size()>0)
	{
		while(m_Vias.empty() == false)
		{
			pvia = m_Vias.front();
			m_Vias.pop_front();
			delete pvia;
		}
		for(std::list<CSIPVia *>::const_iterator i = other.m_Vias.begin();i!=other.m_Vias.end();i++)
		{
			m_Vias.push_back(new CSIPVia(**i));
		}
	}
	else
	{		
		while(!m_Vias.empty())
		{
			pvia = m_Vias.front();	
			m_Vias.pop_front();
			delete pvia;		
		}		
	}
	if(other.m_pMIMEVersion)
	{
		if(m_pMIMEVersion == NULL)
			m_pMIMEVersion = new CSIPMIMEVersion;
		*m_pMIMEVersion = *other.m_pMIMEVersion;
	}
	else if(m_pMIMEVersion)
	{
		delete m_pMIMEVersion;
		m_pMIMEVersion = NULL;
	}

	
	COPYOBJECT(CSIPRequire,m_Requires,other,pri,ri);

	
	COPYOBJECT(CSIPAcceptEncoding,m_AcceptEncodings,other,pace,pecei);
	COPYOBJECT(CSIPAcceptLanguage,m_AcceptLanguages,other,pal,pali);
	eee1(other);
	this->m_Destination = other.m_Destination;
	this->m_Source = other.m_Source;
	this->m_strTransactionID = other.m_strTransactionID;

	 //yb added 20100203{
    this->m_usProduceTime = other.m_usProduceTime; //the time sip is created
    this->m_usRequestTime = other.m_usRequestTime;
    this->m_pTransaction = other.m_pTransaction;
    //yb added 20100203}
	return *this;

}
void CSIPMessage::eee1(const CSIPMessage& other)
{
	if(other.m_pProxyAuthenticate)
	{
		if(m_pProxyAuthenticate == NULL)
			m_pProxyAuthenticate = new CSIPProxyAuthenticate;
		*m_pProxyAuthenticate = *other.m_pProxyAuthenticate;
	}
	
	else if(this->m_pProxyAuthenticate)
	{
		delete m_pProxyAuthenticate;
		m_pProxyAuthenticate = NULL;
	}

//#ifdef PC_CLIENT
	if(other.m_pReplyTo)
	{
		if(m_pReplyTo == NULL)
			m_pReplyTo = new CSIPReplyTo;
		*m_pReplyTo = *other.m_pReplyTo;
	}
	else if(m_pReplyTo)
	{
		delete m_pReplyTo;
		m_pReplyTo = NULL;
	}

	if(other.m_pTimestamp)
	{
		if(m_pTimestamp == NULL)
			m_pTimestamp = new CSIPTimestamp;
		*m_pTimestamp = *other.m_pTimestamp;
	}
	else if(this->m_pTimestamp)
	{
		delete m_pTimestamp;
		m_pTimestamp = NULL;
	}
	if(other.m_pOrganization)
	{
		if(m_pOrganization == NULL)
			m_pOrganization = new CSIPOrganization;
		*m_pOrganization = *other.m_pOrganization;
	}
	else if(this->m_pOrganization)
	{
		delete m_pOrganization;
		m_pOrganization = NULL;
	}
	if(other.m_pServer)
	{
		if(m_pServer == NULL)
			m_pServer = new CSIPServer;
		*m_pServer = *other.m_pServer;
	}
	else if(m_pServer)
	{
		delete m_pServer;
		m_pServer = NULL;
	}
//#endif
	if(other.m_pAuthorization)
	{
		if(m_pAuthorization == NULL)
			m_pAuthorization = new CSIPAuthorization;
		*m_pAuthorization = *other.m_pAuthorization;
	}
	else if(m_pAuthorization)
	{
		delete m_pAuthorization;
		m_pAuthorization = NULL;
	}
	if(other.m_pProxyAuthorization)
	{
		if(m_pProxyAuthorization == NULL)
			m_pProxyAuthorization = new CSIPProxyAuthorization;
		*m_pProxyAuthorization = *other.m_pProxyAuthorization;
	}
	else if(m_pProxyAuthorization)
	{
		delete m_pProxyAuthorization;
		m_pProxyAuthorization = NULL;
	}
	if(other.m_pWWWAuthenticate)
	{
		if(m_pWWWAuthenticate == NULL)
			m_pWWWAuthenticate = new CSIPWWWAuthenticate;
		*m_pWWWAuthenticate = *other.m_pWWWAuthenticate;
	}
	else if(m_pWWWAuthenticate)
	{
		delete m_pWWWAuthenticate;
		m_pWWWAuthenticate = NULL;
	}
	
	if(other.m_pDate)
	{
		if(this->m_pDate)
			delete m_pDate;
		m_pDate = new CSIPDate(*other.m_pDate);
	}
	else if(this->m_pDate)
	{
		delete m_pDate;
		m_pDate = NULL;
	}

	if(other.m_UnknownHeaders.size()>0)
	{
		for(std::list<CSIPUnknown *>::const_iterator i = other.m_UnknownHeaders.begin();i!=other.m_UnknownHeaders.end();i++)
		{
			m_UnknownHeaders.push_back(new CSIPUnknown(**i));
		}
	}
	else
	{
		CSIPUnknown *pvia;
		while(!m_UnknownHeaders.empty())
		{
			pvia = m_UnknownHeaders.front();	
			m_UnknownHeaders.pop_front();
			delete pvia;		
		}		
	}
	
	if(other.m_pTranslate)
	{
		m_pTranslate = new CSIPTranslate(*other.m_pTranslate);
	}
	else if(m_pTranslate)
	{
		delete m_pTranslate;
		m_pTranslate = NULL;
	}
	
	if(other.m_pSubscriptionState)
	{
		m_pSubscriptionState = new CSIPSubscriptionState(*other.m_pSubscriptionState);
	}
	else if(m_pSubscriptionState)
	{
		delete m_pSubscriptionState;
		m_pSubscriptionState = NULL;
	}
}


